package com.zzyl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.aliyun.iot20180120.Client;
import com.aliyun.iot20180120.models.*;
import com.github.pagehelper.PageHelper;
import com.zzyl.base.PageResponse;
import com.zzyl.constant.CacheConstants;
import com.zzyl.dto.DeviceDto;
import com.zzyl.entity.Device;
import com.zzyl.enums.BasicEnum;
import com.zzyl.enums.DevicePhysicalLocationTypeEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.mapper.DeviceMapper;
import com.zzyl.properties.AliIoTConfigProperties;
import com.zzyl.service.DeviceService;
import com.zzyl.vo.DeviceVo;
import com.zzyl.vo.ProductVo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.Collections;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description DeviceServiceImpl
 * @Author huangdongye
 * @Date 2025-05-19  16:35
 */
@Service
public class DeviceServiceImpl implements DeviceService {
    @Autowired
    private AliIoTConfigProperties aliIoTConfigProperties;
    @Autowired
    private Client client;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Autowired
    private DeviceMapper deviceMapper;

    /**
     * 同步产品列表
     */
    @Override
    public void syncProductList() {
        // 创建查寻产品列表的请求对象
        QueryProductListRequest request = new QueryProductListRequest();
        request.setCurrentPage(1)
                .setPageSize(200)
                .setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());

        // 调用阿里接口
        QueryProductListResponse response = null;
        try {
            response = client.queryProductList(request);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_LIST_PRODUCT_ERROR);
        }
        // 接口是否成功
        if (!response.getBody().getSuccess()) {
            throw new RuntimeException(response.getBody().getErrorMessage());
        }

        // 获取产品列表
        List<ProductVo> productList = response.getBody().getData().getList().getProductInfo().stream()
                .map(productInfo -> BeanUtil.toBean(productInfo, ProductVo.class))
                .collect(Collectors.toList());
        // 加入缓存
        redisTemplate.opsForValue().set(CacheConstants.ALL_PRODUCT_KEY, JSONUtil.toJsonStr(productList));
    }

    /**
     * 查询所有产品列表
     *
     * @return List<ProductVo>
     */
    @Override
    public List<ProductVo> allProduct() {
        // 缓存中获取
        String resultRedis = redisTemplate.opsForValue().get(CacheConstants.ALL_PRODUCT_KEY);
        if (ObjectUtil.isEmpty(resultRedis)) {
            return Collections.emptyList();
        }

        return JSONUtil.toList(resultRedis, ProductVo.class);
    }

    /**
     * 注册设备
     *
     * @param deviceDto 设备信息
     */
    @Override
    public void RegisterDevice(DeviceDto deviceDto) {
        // 1.检测数据库是否有该设备名字重复
        Long resultCount = deviceMapper.countByDeviceName(deviceDto.getDeviceName());
        if (resultCount > 0) {
            throw new BaseException(BasicEnum.DEVICE_NAME_EXIST);
        }
        // 2.组装请求参数
        RegisterDeviceRequest registerDeviceRequest = deviceDto.getRegisterDeviceRequest();
        registerDeviceRequest.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        // 3.新增调用接口设备
        RegisterDeviceResponse Response = null;
        try {
            Response = client.registerDevice(registerDeviceRequest);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.DEVICE_NAME_EXIST);
        }
        // 4.检查是否成功The device already exists
        if (!Response.getBody().getSuccess()) {
            throw new RuntimeException(Response.getBody().getErrorMessage());
        }
        // 5.将传入参数转成pojo
        Device bean = BeanUtil.toBean(deviceDto, Device.class);
        // 6.在传入参数中设置iotId,和调用接口后的body
        bean.setIotId(Response.getBody().getData().getIotId());
        // 7.判断是什么类型设备
        if (bean.getLocationType().equals(DevicePhysicalLocationTypeEnum.ELDER.getOrdinal())) {
            bean.setPhysicalLocationType(DevicePhysicalLocationTypeEnum.ELDER.getOrdinal());

        }
        // 8. 在缓存中找到产品名称
        List<ProductVo> productList = allProduct();
        ProductVo productVo = productList.stream().filter(product -> product.getProductKey().equals(bean.getProductKey())).findFirst().orElse(null);
        bean.setProductName(productVo.getProductName());
        bean.setDeviceDescription(productVo.getProductName());

        // 9.插入数据库
        deviceMapper.insertSelective(bean);
    }

    /**
     * 分页查询设备
     *
     * @param page         页码
     * @param size         页大小
     * @param deviceName   设备名称
     * @param locationType 设备位置类型
     * @param productKey   产品key
     * @return PageResponse<Device>
     */
    @Override
    public PageResponse<Device> pageQueryDevice(Integer page, Integer size, String deviceName, Integer locationType, String productKey) {
        PageHelper.startPage(page, size);
        List<Device> result = deviceMapper.pageQueryDevice(page, size, deviceName, locationType, productKey);
        PageResponse<Device> pageResponse = PageResponse.of(result);

        return pageResponse;
    }

    /**
     * 查询设备详情
     *
     * @param iotId      设备id
     * @param productKey 产品key
     */
    @Override
    public DeviceVo QueryDeviceDetail(QueryDeviceDetailRequest queryDeviceDetailRequest) {
        queryDeviceDetailRequest.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        QueryDeviceDetailResponse Response = null;
        try {
            Response = client.queryDeviceDetail(queryDeviceDetailRequest);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        if (Response.getBody().getSuccess()) {
            DeviceVo deviceVo = deviceMapper.selectByIotId(Response.getBody().getData().getIotId());
            BeanUtil.copyProperties(Response.getBody().getData(), deviceVo);
            return deviceVo;
        }
        return null;

    }
    /**
     * 查询设备属性
     *
     *
     * @param productKey 产品key
     */
    @Override
    public QueryThingModelPublishedResponseBody.QueryThingModelPublishedResponseBodyData QueryThingModelPublished(QueryThingModelPublishedRequest request) {
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        QueryThingModelPublishedResponse response = null;
        try {
            response = client.queryThingModelPublished(request);
        }catch (Exception e){
            throw new RuntimeException(response.getBody().errorMessage);
        }
        if (response.getBody().getSuccess()){
            return BeanUtil.toBean(response.getBody().getData(),QueryThingModelPublishedResponseBody.QueryThingModelPublishedResponseBodyData.class);
        }
        return null;
    }
    /**
     * 查询设备属性状态
     *
     * @param productKey 产品key
     */
    @Override
    public QueryDevicePropertyStatusResponseBody.QueryDevicePropertyStatusResponseBodyData QueryDevicePropertyStatus(QueryDevicePropertyStatusRequest request) {
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        QueryDevicePropertyStatusResponse queryDevicePropertyStatusResponse = null;
        try {
            queryDevicePropertyStatusResponse = client.queryDevicePropertyStatus(request);
        } catch (Exception e) {
            throw new RuntimeException(queryDevicePropertyStatusResponse.getBody().getErrorMessage());
        }
        if (queryDevicePropertyStatusResponse.getBody().getSuccess()){
            return BeanUtil.toBean(queryDevicePropertyStatusResponse.getBody().getData(),QueryDevicePropertyStatusResponseBody.QueryDevicePropertyStatusResponseBodyData.class);
        }
        return null;
    }
    /**
     * 更新设备
     * @param productKey 产品key
     */
    @Override
    public void UpdateDevice(DeviceDto deviceDto) {
        // 查询数据库是否存在
        Long count = deviceMapper.getById(deviceDto.getId());
        if (count == 0) {
            throw new BaseException(BasicEnum.DEVICE_NOT_EXIST);
        }
        BatchUpdateDeviceNicknameRequest Request = new BatchUpdateDeviceNicknameRequest();
        BatchUpdateDeviceNicknameRequest.BatchUpdateDeviceNicknameRequestDeviceNicknameInfo bean = BeanUtil.toBean(deviceDto, BatchUpdateDeviceNicknameRequest.BatchUpdateDeviceNicknameRequestDeviceNicknameInfo.class);
        Request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        Request.setDeviceNicknameInfo(List.of(bean));
        //调用接口BatchUpdateDeviceNicknameRequestDeviceNicknameInfo
        BatchUpdateDeviceNicknameResponse batchUpdateDeviceNicknameResponse = null;
        try {
            batchUpdateDeviceNicknameResponse = client.batchUpdateDeviceNickname(Request);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.DEVICE_NAME_EXIST);
        }
        if (!batchUpdateDeviceNicknameResponse.getBody().getSuccess()){
            throw new RuntimeException(batchUpdateDeviceNicknameResponse.getBody().getErrorMessage());
        }
        //        BatchUpdateDeviceNickname
        //修改数据库
        deviceMapper.UpdateDevice(deviceDto);
    }

    /**
     * 删除设备
     * @param productKey 产品key
     */
    @Override
    public void DeleteDevice(DeleteDeviceRequest deleteDeviceRequest) {
        deleteDeviceRequest.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        // 1.删除设备,使用iotId数据库有没有该设备
        Long count = deviceMapper.getByIot(deleteDeviceRequest.getIotId());
        if (count == 0) {
            throw new BaseException(BasicEnum.DEVICE_NOT_EXIST);
        }
        DeleteDeviceResponse deleteDeviceResponse = null;
        // 2.删除阿里云设备
        try {
            deleteDeviceResponse = client.deleteDevice(deleteDeviceRequest);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_DELETE_DEVICE_ERROR);
        }
        if (!deleteDeviceResponse.getBody().getSuccess()){
            throw new RuntimeException(deleteDeviceResponse.getBody().getErrorMessage());
        }
        // 3.删除数据库设备
        deviceMapper.deleteByIotId(deleteDeviceRequest.getIotId());
    }
}
